﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Linq;

namespace Crocodoc
{
    /// <summary>
    /// Provides access to the Crocodoc Document API. The Document API is used for
    /// uploading, checking status, and deleting documents.
    /// </summary>
    public class CrocodocDocument : Crocodoc
    {
        /// <summary>
        /// The Session API path relative to the base API path.
        /// </summary>
        private static string _path = "document/";

        /// <summary>
        /// Gets or sets the Session API path relative to the base API path.
        /// </summary>
        public new static string Path
        {
            get
            {
                return _path;
            }
            set
            {
                _path = value;
            }
        }

        /// <summary>
        /// Deletes a file on Crocodoc by its UUID.
        /// </summary>
        /// <param name="uuid">The uuid of the file to delete.</param>
        /// <returns>Whether or not the file was deleted.</returns>
        public static bool Delete(string uuid)
        {
            NameValueCollection postParams = new NameValueCollection();
            postParams.Add("uuid", uuid);

            return PostRequest<bool>(Path, "delete", postParams);
        }

        /// <summary>
        /// Check the status of a file on Crocodoc by UUID. Takes one UUID string and returns an array that contains one status for that UUID.
        /// </summary>
        /// <param name="uuid">The uuid of the file to check the status of.</param>
        /// <returns>An array of document statuses.</returns>
        public static DocumentStatus Status(string uuid)
        {
            return Status(new string[] { uuid }).FirstOrDefault();
        }

        /// <summary>
        /// Checks the statuses of files on Crocodoc by their UUIDs. Takes an array of UUIDs
        /// and return an array of status arrays about those UUIDs, or can also take
        /// one UUID string and return one status array for that UUID.
        /// </summary>
        /// <param name="uuids">The uuids of the file to check the status for.</param>
        /// <returns>An array of document statuses.</returns>
        public static DocumentStatus[] Status(IEnumerable<string> uuids)
        {
            NameValueCollection getParams = new NameValueCollection();
            string ids = String.Join(",", uuids.ToArray());
            getParams.Add("uuids", ids);

            return GetRequest<DocumentStatus[]>(Path, "status", getParams);
        }

        /// <summary>
        /// Upload a file to Crocodoc using a URL.
        /// </summary>
        /// <param name="url">The url of the file to upload</param>
        /// <returns>An UploadResult, which contains the UUID on success, or an error if there was one.</returns>
        public static UploadResult UploadUrl(string url)
        {
            NameValueCollection postParams = new NameValueCollection();
            postParams.Add("url", url);

            return PostRequest<UploadResult>(Path, "upload", postParams);
        }

        /// <summary>
        /// Uploads a file to Crocodoc using a local filepath.
        /// </summary>
        /// <param name="filepath">The filepath of the file.</param>
        /// <returns>An UploadResult, which contains the UIUD on success, or an error if there was one.</returns>
        public static UploadResult UploadFile(string filepath)
        {
            using (FileStream fs = File.Open(filepath, FileMode.Open))
            {
                return PostFile<UploadResult>(Path, "upload", fs, System.IO.Path.GetFileName(filepath), null);
            }
        }

        /// <summary>
        /// Uploads a file to Crocodoc using a file's byte array.
        /// </summary>
        /// <param name="filename">The name of the file.</param>
        /// <param name="binary">The file's byte array.</param>
        /// <returns>An UploadResult, which contains the UIUD on success, or an error if there was one.</returns>
        public static UploadResult UploadFile(string filename, byte[] binary)
        {
            using (MemoryStream ms = new MemoryStream(binary))
            {
                return PostFile<UploadResult>(Path, "upload", ms, filename, null);
            }
        }
    }
}
